home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 409_01 / svgac.c < prev    next >
C/C++ Source or Header  |  1993-10-21  |  26KB  |  733 lines

  1. /****************************************************************************
  2. *
  3. *                          SuperVGA Test Library
  4. *
  5. *                   Copyright (C) 1993 SciTech Software
  6. *                           All rights reserved.
  7. *
  8. * Filename:     $RCSfile: svgac.c $
  9. * Version:      $Revision: 1.3 $
  10. *
  11. * Language:     ANSI C
  12. * Environment:  IBM PC (MSDOS)
  13. *
  14. * Description:  Simple library to collect together the functions in the
  15. *               SuperVGA test library for use in other C programs. The
  16. *               support is reasonably low level, so you can do what you
  17. *               want. The set of routines in this source file are general
  18. *               SuperVGA routines and are independant of the video mode
  19. *               selected.
  20. *
  21. *               MUST be compiled in the large model.
  22. *
  23. * $Id: svgac.c 1.3 1993/10/22 08:58:40 kjb release $
  24. *
  25. ****************************************************************************/
  26.  
  27. #include <string.h>
  28. #include <dos.h>
  29. #include <stdlib.h>
  30. #include "svga.h"
  31. #include "vesavbe.h"
  32.  
  33. /*---------------------------- Global Variables ---------------------------*/
  34.  
  35. #define MAXMODES    50              /* Maximum modes available in list  */
  36.  
  37. int     maxx,maxy,memory;
  38. long    maxcolor,defcolor;
  39. int     maxpage,bytesperline;
  40. uchar    redMask,greenMask,blueMask;
  41. int        redPos,redAdjust;
  42. int        greenPos,greenAdjust;
  43. int        bluePos,blueAdjust;
  44. bool    twobanks = false,extendedflipping = false,widedac = false;
  45. short   modeList[MAXMODES];
  46. char    OEMString[80];
  47.  
  48. int     oldMode;                    /* Old video mode number            */
  49. bool    old50Lines;                 /* Was old mode 80x50?              */
  50. int     curBank;                    /* Current read/write bank          */
  51. int     bankAdjust;                 /* Bank granularity adjust factor   */
  52. long    pagesize;                   /* Page size for current mode       */
  53. void    *bankSwitch;                /* Pointer to bank switch routine   */
  54. void    *writeBank;                 /* Relocated write bank routine     */
  55. void    *readBank;                  /* Relocated read bank routine      */
  56. void    *pageFlip;                  /* Relocated page flip routine      */
  57. void     (*putPixel)(int x,int y,long color);
  58. void     (*clear)(void);
  59.  
  60. /*----------------------------- Implementation ----------------------------*/
  61.  
  62. /* Declare all video mode dependent routines */
  63.  
  64. void _putPixel16(int x,int y,long color);
  65. void _putPixel256(int x,int y,long color);
  66. void _putPixel32k(int x,int y,long color);
  67. void _putPixel64k(int x,int y,long color);
  68. void _putPixel16m(int x,int y,long color);
  69. void _clear16(void);
  70. void _clear256(void);
  71. void _clear32k(void);
  72. void _clear64k(void);
  73. void _clear16m(void);
  74.  
  75. PRIVATE bool checkVESAPageFlip(void)
  76. /****************************************************************************
  77. *
  78. * Function:     checkVESAPageFlip
  79. * Returns:      True if VBE supports page flipping.
  80. *
  81. * Description:  Determines if the VESA VBE supports extended page
  82. *               flipping or not. Assume a suitable video mode has already
  83. *               been initialised.
  84. *
  85. ****************************************************************************/
  86. {
  87.     union REGS  regs;
  88.  
  89.     regs.x.ax = 0x4F07;         /* Set display start service            */
  90.     regs.x.bx = 0;              /* BH := 0, BL := 0 (set display start) */
  91.     regs.x.cx = 0;              /* Leftmost pixel in line               */
  92.     regs.x.dx = 0;              /* First displayed scanline             */
  93.     int86(0x10,®s,®s);
  94.     if (regs.x.ax != 0x004F)
  95.         return false;           /* Function failed, not page flip       */
  96.  
  97.     regs.x.ax = 0x4F07;         /* Get display start service            */
  98.     regs.x.bx = 1;              /* BH := 0, BL := 1 (get display start) */
  99.     int86(0x10,®s,®s);
  100.     if (regs.x.ax != 0x004F)
  101.         return false;           /* Function failed, not page flip       */
  102.     if (regs.h.bh != 0)
  103.         return false;
  104.     if (regs.x.cx != 0)
  105.         return false;
  106.     if (regs.x.dx != 0)
  107.         return false;
  108.     return true;
  109. }
  110.  
  111. bool checkWideDAC(void)
  112. /****************************************************************************
  113. *
  114. * Function:     checkWideDAC
  115. * Returns:      True if 8 bit wide DAC is supported.
  116. *
  117. * Description:  Tests to see if the VBE BIOS supports an 8 bit wide
  118. *               DAC. This assumes the video card is in an appropriate
  119. *               video mode before being called.
  120. *
  121. ****************************************************************************/
  122. {
  123.     union REGS  regs;
  124.     short       bits;
  125.  
  126.     regs.x.ax = 0x4F08;         /* Set DAC service                      */
  127.     regs.x.bx = 0x0800;         /* BH := 8, BL := 0 (set DAC width)     */
  128.     int86(0x10,®s,®s);
  129.     if (regs.x.ax != 0x004F)
  130.         return false;           /* Function failed, no wide dac         */
  131.     if (regs.h.bh == 6)
  132.         return false;
  133.     regs.x.ax = 0x4F08;
  134.     regs.x.bx = 0x0001;         /* Get DAC width (should now be 8)      */
  135.     int86(0x10,®s,®s);
  136.     if (regs.x.ax != 0x004F)
  137.         return false;
  138.     bits = regs.h.bh;
  139.     regs.x.ax = 0x4F08;
  140.     regs.x.bx = 0x0600;
  141.     int86(0x10,®s,®s);    /* Restore to 6 bit DAC                 */
  142.     if (regs.x.ax != 0x004F)
  143.         return false;
  144.  
  145.     return (bits == 8);
  146. }
  147.  
  148. PUBLIC int initSuperVGA(void)
  149. /****************************************************************************
  150. *
  151. * Function:     initSuperVGA
  152. * Returns:      VBE version number for the SuperVGA (0 if no SuperVGA).
  153. *
  154. * Description:  Detects if a VESA VBE compliant SuperVGA is out there, and
  155. *               initialises the library if one is. The VBE version number
  156. *               is specified with the major version number in the high
  157. *               byte and the minor version number in the low byte. So
  158. *               version 1.2 is the number 0x102.
  159. *
  160. ****************************************************************************/
  161. {
  162.     VgaInfoBlock    vgaInfo;
  163.     ModeInfoBlock   modeInfo;
  164.     union REGS      regs;
  165.     struct SREGS    sregs;
  166.     short           *p,i;
  167.  
  168.     sregs.es = SEG(&vgaInfo);
  169.     regs.x.di = OFF(&vgaInfo);
  170.     regs.x.ax = 0x4F00;
  171.     int86x(0x10,®s,®s,&sregs);    /* Get SuperVGA information     */
  172.     if (regs.x.ax != 0x004F)
  173.         return false;
  174.     if (strncmp(vgaInfo.VESASignature,"VESA",4) != 0)
  175.         return false;
  176.  
  177.     /* Copy relavent information from the mode block into our globals.
  178.      * Note that the video mode list _may_ be built in the information
  179.      * block that we have passed, so we _must_ copy this from here
  180.      * into our our storage if we want to continue to use it. Note
  181.      * that we filter out the mode 0x6A, which some BIOSes include as
  182.      * well as the 0x102 mode for 800x600x16.
  183.      */
  184.  
  185.     for (i = 0,p = vgaInfo.VideoModePtr; *p != -1; p++,i++) {
  186.         if (*p != 0x6A)
  187.             modeList[i] = *p;
  188.         }
  189.     modeList[i] = -1;
  190.     memory = vgaInfo.TotalMemory * 64;
  191.     strcpy(OEMString,vgaInfo.OEMStringPtr);
  192.  
  193.     /* Determine if the board supports separate read/write banks and
  194.      * extended page flipping. Some VESA VBE's require the card to be
  195.      * in a graphics mode for these tests to work, so we find a suitable
  196.      * mode and use that.
  197.      */
  198.  
  199.     for (p = modeList; *p != -1; p++) {
  200.         sregs.es = SEG(&modeInfo);
  201.         regs.x.di = OFF(&modeInfo);
  202.         regs.x.ax = 0x4F01;
  203.         regs.x.cx = *p;
  204.         int86x(0x10,®s,®s,&sregs);    /* Get SuperVGA mode info   */
  205.         if (regs.x.ax == 0x004F &&
  206.                 (modeInfo.MemoryModel == 3 || modeInfo.MemoryModel == 4)) {
  207.             modeInfo.WinBAttributes &= 0x7;
  208.             twobanks = (modeInfo.WinBAttributes == 0x3);
  209.             setSuperVGAMode(*p);
  210.             extendedflipping = checkVESAPageFlip();
  211.             widedac = checkWideDAC();
  212.             restoreMode();
  213.             break;
  214.             }
  215.         }
  216.  
  217.     return vgaInfo.VESAVersion;
  218. }
  219.  
  220. PRIVATE void computePageInfo(ModeInfoBlock *modeInfo,int *maxpage,
  221.     long *pages